#include "base/logfile.h"
#include "base/logstream.h"
#include "base/thread.h"
#include "base/config.h"

#include <unistd.h>
#include <sys/syscall.h>

#include "base/log.h"

namespace net_tools{

__thread base::Logstream* Log::logstream_ = nullptr;
base::Logfile* Log::logfile_ = nullptr;
base::Logstream::Log_level Log::level_ = static_cast<base::Logstream::Log_level>(_C::SET_LOG_OUTPUT_LEVEL);
func Log::flush_ = Log::Defaultflush;
Log::outputfunc Log::output_ = Log::Defaultoutput;


Log::Log(std::string app_name)
  :app_name_(std::move(app_name))
{
  Init();
};
Log::~Log(){
};
base::Logstream* Log::Init(){
  base::Thread::thread_tid_ = syscall(SYS_gettid);
  static base::Logstream logstream(base::Thread::thread_tid_);
  if(!logstream_){
    logstream_ = &logstream;
    return logstream_;
  }
  return nullptr;
};
void Log::Init(net_tools::Eventloop* eventloop,FILE* file_stream){
  Log::logfile_ = new base::Logfile(app_name_,eventloop,file_stream);
  flush_ = Flush;
  output_ = Output;
  NT_LOG_TRACE << "LOGSTREAM OK" << NT_LOG_ENDL;
};
void Log::Use_file_flush_file(){
  Log::logfile_->Use_file_flush_file();
};
void Log::Set_level(base::Logstream::Log_level level){
  level_ = level;
};
void Log::Setstream(FILE* stream){
  Log::logfile_->Setstream(stream);
};
void Log::Flush(){
  Log::logfile_->Flush();
};
void Log::Output(void* address,short int len){
  Log::logfile_->Output(address,len);
};
void Log::Defaultflush(){
  fflush(stdout);
};
void Log::Defaultoutput(void* address,short int len){
  fwrite_unlocked(address,1,len,stdout);
};

} // namespace net_tools